package com.lanyou.cook.web;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.pentaho.di.core.encryption.Encr;
import org.pentaho.di.core.encryption.KettleTwoWayPasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.JsonObject;
import com.lanyou.cook.common.Constants;
import com.lanyou.cook.datadictionary.UserLogOpt;
import com.lanyou.cook.entity.domain.DBlink;
import com.lanyou.cook.entity.domain.DBlinkDataSource;
import com.lanyou.cook.repository.DBlinkDataSourceRepository;
import com.lanyou.cook.repository.DBlinkRepository;
import com.lanyou.cook.service.UserLogService;
import com.lanyou.cook.util.RSAUtil;
import com.lanyou.cook.web.param.DBlinkDataSourceParam;
/**
 * 
 * @author 曾族根
 *
 */ 
@RestController
@RequestMapping(Constants.BASE_URL_API + "/dBlinkDataSources")
public class DBlinkDataSourceController {
	@Autowired
	private UserLogService userLogService;
	@Autowired
	private DBlinkDataSourceRepository dblinkDataSourceRepository;
	@Autowired
	private DBlinkRepository dblinkRepository;
	/**
	 * 查询dblink数据库链接
	 * @param param 类型:String 
	 * @param pageable 类型:String
	 * @return
	 */
	@RequestMapping("/search/findByExample")
	@RequiresPermissions(value={"dbLinkDatabaseLinkManagement:view","dbLinkDatabaseLinkManagement:maintain"},logical=Logical.OR)
	public Page<DBlinkDataSource> findByExample(DBlinkDataSourceParam param, Pageable pageable) {
		
		Specification<DBlinkDataSource> spec = new Specification<DBlinkDataSource>() {
			@Override
			public Predicate toPredicate(Root<DBlinkDataSource> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicatesList = new ArrayList<>();
				if(StringUtils.isNotBlank(param.getName())){
					predicatesList.add(cb.like(root.get("name"), '%' + param.getName() + '%'));
				}
				
				if(StringUtils.isNotBlank(param.getDbname())){
					predicatesList.add(cb.like(root.get("dbname"), '%' + param.getDbname() + '%'));
				}
				
				query.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
				return null;
			}
		};
		return dblinkDataSourceRepository.findAll(spec, pageable);
	}
	@RequestMapping(value = "/search/checkIsCanSave", produces = "application/json")
	public String checkIsCanSave(String name,String host,String originalId) {
		DBlinkDataSource dblinkDataSource = dblinkDataSourceRepository.findByNameAndHost(name,host);
		if (dblinkDataSource != null) {
			if (!StringUtils.equals(dblinkDataSource.getId(), originalId)) {
				JsonObject result = new JsonObject();
				result.addProperty("isCanSave", false);
				result.addProperty("reason", "数据库中已存在，不能保存！");
				return result.toString();
			}
		}

		JsonObject result = new JsonObject();
		result.addProperty("isCanSave", true);
		return result.toString();
	} 
	
	
	@RequestMapping(value = "/saveOrUpdate", produces = "application/json", method=RequestMethod.POST)
	public String savaOrUpdate(@RequestBody DBlinkDataSourceParam param){
		boolean flag = false;
		DBlinkDataSource dblinkDateSource = dblinkDataSourceRepository.findOne(param.getId());
		if(dblinkDateSource==null){
			dblinkDateSource = new DBlinkDataSource();
			flag= true;
		}
		JsonObject result = new JsonObject();
		DBlinkDataSource dblinkDataSource = dblinkDataSourceRepository.findByNameAndHost(param.getName(),param.getDbname());
		if (dblinkDataSource != null) {
			if (!StringUtils.equals(dblinkDataSource.getId(), param.getId())) {
				result.addProperty("isCanSave", false);
				result.addProperty("reason", "数据库中已存在，不能保存！");
				return result.toString();
			}
		}
		String password =param.getPassword();
		try {
			// 进行RSA解密
		password = RSAUtil.decryptByPrivateKey(param.getPassword(), Constants.PRIVATE_KEY_BASE64);
	    param.setPassword(password);
		} catch (Exception e) {

		}

		if(StringUtils.isEmpty(password))
	    throw new RuntimeException("Password is invalid");
		// 原密码未经过加密，则此时加密
		if(!password.startsWith(KettleTwoWayPasswordEncoder.PASSWORD_ENCRYPTED_PREFIX)){
			String encryptedPassword = Encr.encryptPasswordIfNotUsingVariables(password);
			dblinkDataSource.setPassword(encryptedPassword);
			param.setPassword(encryptedPassword);
		}
		dblinkDataSource.setDbname(param.getDbname());
		dblinkDataSource.setHost(param.getHost());	
		dblinkDataSource.setName(param.getName());
		dblinkDataSource.setPort(param.getPort());
		dblinkDataSource.setUser(param.getUser());
		
		dblinkDataSourceRepository.save(Arrays.asList(dblinkDataSource));
		if(flag==true){
		userLogService.save(UserLogOpt.MaintenanceDataSource, null,
				String.format("新增了dblik数据库链接“%s”的信息",dblinkDataSource.getName()));
		}else{
		userLogService.save(UserLogOpt.MaintenanceDataSource, null,
				String.format("维护了dblik数据库链接“%s”的信息",dblinkDataSource.getName()));
		}
		return result.toString();
		
	}
	
}
